import { useEffect, useRef, useState } from 'react'
import moment from 'moment'
import { useStrategyBacktest, BASE_CAPITAL, useTradeMarkers } from './index'

function update (chart, data) {
}

const comment = () => {
  return <div>基于拐点算法的定投策略。每次向上拐点买入10%现金，向下拐点卖出：往前找所经历的所有买点，如果满足此次收益&gt;5%就卖掉这部分。</div>
}

const INTERVAL_KEY = 'fixedInvestmentInterval'
const BUY_RATIO_KEY = 'fixedInvestmentBuyRatio'
const SELL_THRESHOLD_KEY = 'fixedInvestmentSellThreshold'

const FixedInvestmentTools = (props) => {
  const [started, setStarted] = useState(false)
  const [autoRun, setAutoRun] = useState(false)
  const [finished, setFinished] = useState(false)
  const [data, setData] = useState([])
  const [currentIndex, setCurrentIndex] = useState(0)
  const [direction, setDirection] = useState('down')
  const [intervalMs, setIntervalMs] = useState(() => {
    if (typeof window !== 'undefined') {
      const stored = localStorage.getItem(INTERVAL_KEY)
      if (stored) {
        const val = Number(stored)
        if (!Number.isNaN(val) && val >= 100 && val <= 5000) {
          return val
        }
      }
    }
    return 500
  })
  // 买入比例：每次买入使用现金的比例（0.1 = 10%）
  const [buyRatio, setBuyRatio] = useState(() => {
    if (typeof window !== 'undefined') {
      const stored = localStorage.getItem(BUY_RATIO_KEY)
      if (stored) {
        const val = Number(stored)
        if (!Number.isNaN(val) && val >= 0.01 && val <= 1) {
          return val
        }
      }
    }
    return 0.1 // 默认10%
  })
  // 卖出阈值：涨幅超过这个值就卖出（0.05 = 5%）
  const [sellThreshold, setSellThreshold] = useState(() => {
    if (typeof window !== 'undefined') {
      const stored = localStorage.getItem(SELL_THRESHOLD_KEY)
      if (stored) {
        const val = Number(stored)
        if (!Number.isNaN(val) && val >= 0.01 && val <= 1) {
          return val
        }
      }
    }
    return 0.05 // 默认5%
  })
  const intervalRef = useRef(intervalMs)
  const autoTimerRef = useRef(null)
  const tradeInfoRef = useRef({
    active: false,
    entryPrice: 0,
    entryTimestamp: null,
    entryIndex: -1,
    overlayId: null
  })
  // 跟踪买入记录，用于计算分批卖出
  const buyRecordsRef = useRef([]) // [{ price, count, timestamp }, ...]
  const downTurningPointCountRef = useRef(0) // 向下拐点计数
  const overlaysRef = useRef([])
  const { addTradeMarker, redrawTradeMarkers, clearTradeMarkers } = useTradeMarkers(props.chart)
  const {
    equityHistory,
    recordEquity,
    registerTrade,
    reset: resetBacktest,
    finalize,
    SummaryModal
  } = useStrategyBacktest()

  // 将 equityHistory 传递给父组件
  useEffect(() => {
    if (props.onEquityHistoryChange) {
      props.onEquityHistoryChange(equityHistory)
    }
  }, [equityHistory])

  useEffect(() => {
    return () => {
      if (autoTimerRef.current) {
        clearInterval(autoTimerRef.current)
      }
    }
  }, [])

  useEffect(() => {
    intervalRef.current = intervalMs
    if (typeof window !== 'undefined') {
      localStorage.setItem(INTERVAL_KEY, String(intervalMs))
    }
  }, [intervalMs])

  useEffect(() => {
    if (typeof window !== 'undefined') {
      localStorage.setItem(BUY_RATIO_KEY, String(buyRatio))
    }
  }, [buyRatio])

  useEffect(() => {
    if (typeof window !== 'undefined') {
      localStorage.setItem(SELL_THRESHOLD_KEY, String(sellThreshold))
    }
  }, [sellThreshold])

  useEffect(() => {
    if (autoTimerRef.current) {
      clearInterval(autoTimerRef.current)
    }
    if (started && autoRun && !finished) {
      autoTimerRef.current = setInterval(() => {
        nextStep()
      }, intervalRef.current)
    }
    return () => {
      if (autoTimerRef.current) {
        clearInterval(autoTimerRef.current)
      }
    }
  }, [autoRun, started, finished, data, currentIndex, buyRatio, sellThreshold])

  const removeTradeOverlay = () => {
    if (tradeInfoRef.current.overlayId && props.chart?.current) {
      try {
        props.chart.current.removeOverlay(tradeInfoRef.current.overlayId)
      } catch (e) {
        // ignore removal failures
      }
    }
    tradeInfoRef.current.overlayId = null
  }

  const clearAllOverlays = () => {
    if (props.chart?.current) {
      overlaysRef.current.forEach(id => {
        try {
          props.chart.current.removeOverlay(id)
        } catch (e) {
          // ignore
        }
      })
    }
    overlaysRef.current = []
    removeTradeOverlay()
    clearTradeMarkers() // 清除买卖标记
  }

  const refreshTradeOverlay = (actualData) => {
    const info = tradeInfoRef.current
    if (!info.active || !props.chart?.current) {
      removeTradeOverlay()
      return
    }
    if (info.entryIndex < 0 || info.entryIndex >= actualData.length) {
      removeTradeOverlay()
      return
    }
    const segment = actualData.slice(info.entryIndex)
    if (!segment.length) {
      removeTradeOverlay()
      return
    }
    // 使用全部数据的最高价和最低价，而不是只使用 segment 的价格
    const maxHigh = Math.max(...actualData.map(bar => bar.high))
    const minLow = Math.min(...actualData.map(bar => bar.low))
    const latestClose = segment[segment.length - 1].close
    const color = latestClose >= info.entryPrice ? 'rgba(255,22,22,0.15)' : 'rgba(13,190,28,0.15)'
    removeTradeOverlay()
    info.overlayId = props.chart.current.createOverlay({
      name: 'rect',
      styles: {
        polygon: {
          color
        }
      },
      points: [
        { timestamp: segment[0].timestamp, value: maxHigh },
        { timestamp: segment[segment.length - 1].timestamp, value: minLow }
      ]
    })
  }

  // 分批买入：买入可用现金的指定比例
  const buyPartial = (price, ratio = 0.1) => {
    const trader = props.trader
    if (!trader || trader.cash <= 0) {
      return false
    }
    
    const buyAmount = trader.cash * ratio
    const count = Math.floor(buyAmount / price)
    
    if (count <= 0) {
      return false
    }
    
    const cost = count * price
    
    // 更新 trader 状态
    trader.cash -= cost
    trader.positionCount = (trader.positionCount || 0) + count
    trader.costBasis = (trader.costBasis || 0) + cost
    trader.price = price
    
    // 记录买入记录
    buyRecordsRef.current.push({
      price,
      count,
      timestamp: Date.now(),
      cost
    })
    
    // 更新持仓信息
    if (!tradeInfoRef.current.active) {
      tradeInfoRef.current = {
        active: true,
        entryPrice: price,
        entryTimestamp: Date.now(),
        entryIndex: -1,
        overlayId: tradeInfoRef.current.overlayId
      }
    }
    
    // 更新 UI
    const positionValue = trader.positionCount * price
    trader.position = positionValue
    trader.props.setPosition(positionValue)
    trader.updateMetrics()
    
    console.log(`✅ 定投买入: 价格=${price.toFixed(2)}, 数量=${count}, 成本=${cost.toFixed(2)}, 现金=${trader.cash.toFixed(2)}`)
    
    return true
  }

  // 分批卖出：每次卖点出现时，往前找所经历的所有买点，如果满足此次收益>5%就卖掉这部分
  const sellPartial = (price) => {
    const trader = props.trader
    if (!trader || !trader.positionCount || trader.positionCount <= 0) {
      return { sold: false, profitRatio: 0, soldCount: 0 }
    }
    
    if (buyRecordsRef.current.length === 0) {
      return { sold: false, profitRatio: 0, soldCount: 0 }
    }
    
    let totalSoldCount = 0
    let totalSoldCost = 0
    let totalSoldValue = 0
    const remainingRecords = []
    
    // 遍历所有买入记录（往前找所经历的所有买点），如果涨幅>sellThreshold就卖出
    for (const record of buyRecordsRef.current) {
      const profitRatio = (price - record.price) / record.price
      
      // 如果涨幅>sellThreshold，卖出这部分
      if (profitRatio > sellThreshold) {
        // 卖出这部分
        totalSoldCount += record.count
        totalSoldCost += record.cost
        totalSoldValue += record.count * price
        console.log(`  - 卖出批次: 买入价=${record.price.toFixed(2)}, 数量=${record.count}, 涨幅=${(profitRatio * 100).toFixed(2)}%`)
      } else {
        // 涨幅<=5%，保留
        remainingRecords.push(record)
      }
    }
    
    if (totalSoldCount <= 0) {
      return { sold: false, profitRatio: 0, soldCount: 0 }
    }
    
    // 更新 trader 状态
    trader.positionCount -= totalSoldCount
    trader.costBasis -= totalSoldCost
    trader.cash += totalSoldValue
    trader.realizedProfit += (totalSoldValue - totalSoldCost)
    trader.price = price
    
    // 更新买入记录
    buyRecordsRef.current = remainingRecords
    
    // 计算平均成本价和收益率
    const avgCostPrice = totalSoldCost / totalSoldCount
    const profitRatio = (price - avgCostPrice) / avgCostPrice
    
    // 更新持仓信息
    if (trader.positionCount <= 0) {
      trader.positionCount = 0
      trader.costBasis = 0
      tradeInfoRef.current = {
        active: false,
        entryPrice: 0,
        entryTimestamp: null,
        entryIndex: -1,
        overlayId: null
      }
    }
    
    // 更新 UI
    const positionValue = trader.positionCount * price
    trader.position = positionValue
    trader.props.setPosition(positionValue)
    trader.updateMetrics()
    
    console.log(`✅ 定投卖出: 价格=${price.toFixed(2)}, 数量=${totalSoldCount}, 成本=${totalSoldCost.toFixed(2)}, 收益=${(totalSoldValue - totalSoldCost).toFixed(2)}, 收益率=${(profitRatio * 100).toFixed(2)}%`)
    
    return {
      sold: true,
      profitRatio,
      soldCount: totalSoldCount,
      avgCostPrice,
      exitPrice: price
    }
  }

  const loadRandomDataset = async () => {
    const stocks = props.stocks ?? []
    if (!stocks.length) {
      return
    }
    const tradable = stocks.filter(stock => {
      return ((stock.code.startsWith('60') && stock.code.endsWith('SH')) ||
        (stock.code.startsWith('00') && stock.code.endsWith('SZ')) ||
        (stock.code.startsWith('30') && stock.code.endsWith('SZ'))) &&
        !stock.name.includes('ST')
    })
    if (!tradable.length) {
      return
    }
    const randomStock = tradable[Math.floor(Math.random() * tradable.length)]
    const dates = (props.dates ?? []).filter(date => {
      return date / 1000 >= randomStock.open && moment.unix(date / 1000).year() <= 2021
    })
    if (!dates.length) {
      return
    }
    const randomDate = dates[Math.floor(Math.random() * dates.length)]
    const dailyData = await props.getKlines(randomStock.code, '1d', randomDate, 600)
    if (!dailyData || !dailyData.length) {
      return
    }
    const startIndex = Math.min(Math.floor(dailyData.length / 2), dailyData.length - 1)
    const initialData = dailyData.slice(0, startIndex)
    setData(dailyData)
    setCurrentIndex(startIndex)
    setDirection('down')
    setFinished(false)
    clearAllOverlays()
    tradeInfoRef.current = {
      active: false,
      entryPrice: 0,
      entryTimestamp: null,
      entryIndex: -1,
      overlayId: null
    }
    buyRecordsRef.current = []
    downTurningPointCountRef.current = 0
    if (props.trader?.reset) {
      props.trader.reset()
    }
    resetBacktest()
    applyChart(initialData)
    const initialTimestamp = initialData.length ? initialData[initialData.length - 1].timestamp : Date.now()
    recordEquity(initialTimestamp, props.trader?.equity ?? BASE_CAPITAL)
    setStarted(true)
    props.setInfoDisplay(false)
  }

  const createGhostBar = (last) => {
    if (!last) {
      return null
    }
    return {
      open: last.close,
      close: last.close,
      high: last.close,
      low: last.close,
      volume: 0,
      amount: 0,
      timestamp: last.timestamp + 24 * 60 * 60 * 1000
    }
  }

  const applyChart = (actualData) => {
    if (!props.chart?.current) {
      return
    }
    if (!actualData.length) {
      props.chart.current.applyNewData([])
      props.onDataApplied?.([])
      return
    }
    const ghost = createGhostBar(actualData[actualData.length - 1])
    const chartData = ghost ? [...actualData, ghost] : [...actualData]
    props.chart.current.applyNewData(chartData)
    if (props.indicatorStrategies) {
      for (const indicatorStrategy of props.indicatorStrategies) {
        if (indicatorStrategy.reset) {
          indicatorStrategy.reset(props.chart.current)
        }
        indicatorStrategy.update(props.chart.current, chartData)
      }
    }
    // applyNewData 清除了所有 overlay，需要重新绘制买卖标记
    redrawTradeMarkers()
    props.onDataApplied?.(chartData)
    if (actualData.length) {
      const latest = actualData[actualData.length - 1]
      props.setPrice?.(latest.close)
    }
  }

  const evaluateTurningPoint = (actualData) => {
    if (actualData.length < 2) {
      return
    }
    const prev = actualData[actualData.length - 2]
    const curr = actualData[actualData.length - 1]
    if (!prev || !curr) {
      return
    }
    let newDirection = direction
    let traded = false
    
    // 向下拐点（买点）：收盘价突破前一日高点
    if ((direction === 'down' || direction == null) && curr.close > prev.high) {
      newDirection = 'up'
      // 在向上拐点之前，记录向下拐点计数
      downTurningPointCountRef.current += 1
      // 买入配置比例的现金
      const bought = buyPartial(curr.close, buyRatio)
      if (bought) {
        addTradeMarker(curr, 'buy', curr.close)
        tradeInfoRef.current.entryIndex = actualData.length - 1
        traded = true
      }
    } 
    // 向上拐点（卖点）：收盘价跌破前一日低点
    else if (direction === 'up' && curr.close < prev.low) {
      newDirection = 'down'
      // 卖出涨幅>20%的部分
      const sellResult = sellPartial(curr.close)
      if (sellResult.sold) {
        addTradeMarker(curr, 'sell', curr.close)
        if (tradeInfoRef.current.overlayId && props.chart?.current) {
          overlaysRef.current.push(tradeInfoRef.current.overlayId)
        }
        // 记录交易（分批卖出可能多次，这里记录总的收益率）
        registerTrade(sellResult.profitRatio, sellResult.avgCostPrice, sellResult.exitPrice)
        console.log('✅ 定投卖出完成:', {
          soldCount: sellResult.soldCount,
          avgCostPrice: sellResult.avgCostPrice,
          exitPrice: sellResult.exitPrice,
          profitRatio: sellResult.profitRatio,
          profitPercent: (sellResult.profitRatio * 100).toFixed(2) + '%',
          timestamp: curr.timestamp
        })
        traded = true
      }
    }
    
    setDirection(newDirection)
    if (!traded) {
      // 如果没有交易，更新持仓市值
      if (props.trader && props.trader.positionCount > 0) {
        props.trader.hold(curr.close)
      }
    }
    if (tradeInfoRef.current.active) {
      refreshTradeOverlay(actualData)
    }
  }

  const nextStep = () => {
    if (!started || finished) {
      return
    }
    const nextIndex = Math.min(currentIndex + 1, data.length)
    if (nextIndex > data.length) {
      return
    }
    const actualData = data.slice(0, nextIndex)
    applyChart(actualData)
    evaluateTurningPoint(actualData)
    const lastTimestamp = actualData.length ? actualData[actualData.length - 1].timestamp : Date.now()
    recordEquity(lastTimestamp, props.trader?.equity ?? BASE_CAPITAL)
    setCurrentIndex(nextIndex)
    if (nextIndex >= data.length) {
      // 回测结束时，如果有持仓，强制平仓
      if (props.trader && props.trader.positionCount > 0) {
        const lastCandle = actualData[actualData.length - 1]
        if (lastCandle) {
          // 卖出所有剩余持仓
          const remainingCount = props.trader.positionCount
          const remainingCost = props.trader.costBasis
          const sellValue = remainingCount * lastCandle.close
          
          props.trader.cash += sellValue
          props.trader.realizedProfit += (sellValue - remainingCost)
          props.trader.positionCount = 0
          props.trader.costBasis = 0
          props.trader.price = lastCandle.close
          props.trader.position = 0
          props.trader.props.setPosition(0)
          props.trader.updateMetrics()
          
          const avgCostPrice = remainingCost / remainingCount
          const profitRatio = (lastCandle.close - avgCostPrice) / avgCostPrice
          
          addTradeMarker(lastCandle, 'sell', lastCandle.close)
          registerTrade(profitRatio, avgCostPrice, lastCandle.close)
          
          console.log('✅ 回测结束强制平仓:', {
            soldCount: remainingCount,
            avgCostPrice,
            exitPrice: lastCandle.close,
            profitRatio,
            profitPercent: (profitRatio * 100).toFixed(2) + '%',
            timestamp: lastCandle.timestamp
          })
        }
      }
      // 等待状态更新再 finalize
      setTimeout(() => {
        setFinished(true)
        setAutoRun(false)
        finalize()
      }, 0)
    }
  }

  const endBacktest = () => {
    if (autoTimerRef.current) {
      clearInterval(autoTimerRef.current)
    }
    clearAllOverlays()
    window.location.reload()
  }

  const stepDisabled = !started || finished
  const autoDisabled = !started || finished

  return (
    <>
      {SummaryModal}
      <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
        <div style={{ display: 'flex', flexDirection: 'row', gap: 12, alignItems: 'center', flexWrap: 'wrap' }}>
          {!started && (
            <button onClick={loadRandomDataset}>开始回测</button>
          )}
          {started && (
          <>
            <button disabled={stepDisabled} onClick={nextStep}>步进</button>
            <button
              disabled={autoDisabled}
              onClick={() => {
                if (finished) return
                setAutoRun(prev => !prev)
              }}
            >
              {autoRun ? '停止自动' : '自动'}
            </button>
            <div style={{display: 'flex', alignItems: 'center', gap: 6}}>
              <div style={{color: 'rgba(255,255,255,0.65)', fontSize: 12}}>速度</div>
              <input
                type="range"
                min={100}
                max={5000}
                step={100}
                value={intervalMs}
                onChange={e => setIntervalMs(Number(e.target.value))}
                style={{width: 160}}
              />
              <div style={{minWidth: 50, textAlign: 'right', color: '#0dd697', fontSize: 12}}>{(intervalMs / 1000).toFixed(1)}s</div>
            </div>
            <div style={{display: 'flex', alignItems: 'center', gap: 6}}>
              <div style={{color: 'rgba(255,255,255,0.65)', fontSize: 12}}>买入比例</div>
              <input
                type="range"
                min={1}
                max={100}
                step={1}
                value={buyRatio * 100}
                onChange={e => setBuyRatio(Number(e.target.value) / 100)}
                style={{width: 120}}
              />
              <div style={{minWidth: 40, textAlign: 'right', color: '#0dd697', fontSize: 12}}>{(buyRatio * 100).toFixed(0)}%</div>
            </div>
            <div style={{display: 'flex', alignItems: 'center', gap: 6}}>
              <div style={{color: 'rgba(255,255,255,0.65)', fontSize: 12}}>卖出阈值</div>
              <input
                type="range"
                min={1}
                max={50}
                step={1}
                value={sellThreshold * 100}
                onChange={e => setSellThreshold(Number(e.target.value) / 100)}
                style={{width: 120}}
              />
              <div style={{minWidth: 40, textAlign: 'right', color: '#ffb74d', fontSize: 12}}>{(sellThreshold * 100).toFixed(0)}%</div>
            </div>
            <button onClick={endBacktest}>结束</button>
          </>
        )}
      </div>
      </div>
    </>
  )
}

export default { update, name: '定投', comment, Tools: FixedInvestmentTools }

